#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<functional>
#include"task.h"

typedef functional<void()> task_t; //定义了一个类型返回值为void typedef 成 task_t函数类型 



void LoadTask(vector<task_t>& tasks)
{
tasks.push_back(PrintLog);
	tasks.push_back(Download);
	tasks.push_back(BackUp);
}
int main()
{
	vector<task_t> tasks;
	LoadTask(tasks);


pid_t id=fork();

if(id==0)
{
//     子进程
	while(true)
	{
	printf("我是子进程，pid: %d\n",getpid());
	sleep(1);
	}
	exit(0);
}
else if(id>0)
{
	//父进程 
	while(true)
	{
		
	pid_t rid=waitpid(id,nullptr,WNOHANG);//父进程需要回收子进程 非阻塞等待
	if(rid>0)
	{
		printf("等待子进程%d成功\n",rid);
			break; //等待成功就不需要再继续while
	}
	else if(rid<0)
	{
		printf("等待子进程失败\n");
		break;//等待失败就不需要再继续while
	}
	else //rid==0时 等待成功 但是子进程没有退出 应该继续while循环 再次等待
	{
		printf("子进程尚未退出\n");

		//父进程做自己的事情
		for(auto& task:tasks)
		{
			task();
		}
	}
	sleep(1);
	}
}

//	pid_t id=fork();
//
//	if(id<0)
//	{
//		printf("errno: %d,errstring: %s\n",errno,strerror(errno));
//		return errno;	
//	}
//	else if(id==0)
//	{
//		int cnt=5;
//		while(cnt)
//		{
//			printf("子进程运行中，pid: %d\n",getpid());
//			cnt--;
//			sleep(1);
//		}
//		exit(1); // 退出码 不想让子进程执行后续的代码，直接退出
//	}
//	else
//	{
////		sleep(10); //直观看出父进程回收僵尸状态的子进程
////	        pid_t rid=wait(nullptr);
//	        int status =0;
//
//	        pid_t rid=waitpid(id,&status,0);// == wait   第一个参数是-1说明是随机回收子进程 >0(id)即子进程的pid 则是指定回收 第二个参数设为nullptr表示不关心子进程的退出结果，如果关心则 &status
//		if(rid>0) //返回值rid >0 说明回收成功  回收值就是子进程的rid
//		{	
//		      	if(WIFEXITED(status))
//			{
//		 	    printf("wait sub process success,rid: %d,status code:%d\n",rid,WEXITSTATUS(status));
//		        }
//			else
//			{
//				printf("child process quit error!\n");
//			}
//		}
//		else  // 回收失i败
//		{
//			perror("waitpid");
//		}
//
//		while(true)
//		{
//		printf("我是父进程，pid:%d\n",getpid());
//		sleep(1);
//		}
//	}
////	for(int i=0;i<200;i++)
////	{
////	cout<<"code: "<<i<<",errstring:"<<strerror(i)<<endl;
////	}
////	printf("before: errno: %d, errstring: %s\n",errno,strerror(errno));
////
////	FILE* fp=fopen("./log.txt","r");
////	if(fp==nullptr)
////	{
////	 printf("after: errno: %d, errstring: %s\n",errno,strerror(errno));
////	 return errno;
////	}
     return 0;
     }
